﻿#region

using System;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Windows;
using AppExceptions;
using System.Linq;
using MCDomain.DataAccess;
using MContracts.Classes;
using MContracts.ViewModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Telerik.Windows.Controls;
using Ninject;
using MCDomain.AOP;
using CommonBase;

#endregion


namespace MContracts
{
    /// <summary>
    ///   Interaction logic for App.xaml
    /// </summary>

    public partial class App : Application
    {
        private static IKernel _kernel;

        private static IKernel Kernel
        {
            get
            {
                if (_kernel == null)
                    SetupBinds();

                return _kernel;
            }
        }

        private const string DEFAULT_POLICY = "DefaultExceptionPolicy";

        private static ExceptionManager _manager;

        /// <summary>
        ///   Получает менеджер исключений
        /// </summary>
        public static ExceptionManager ExceptionManager
        {
            get
            {
                Contract.Ensures(Contract.Result<ExceptionManager>() != null);
                return _manager ?? (_manager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>());
            }
        }


        public static string FileVersionInfo
        {
            get { return Assembly.GetEntryAssembly().AssemblyFileVersion(); }
        }

        public static string AssemblyVersionInfo
        {
            get { return Assembly.GetEntryAssembly().AssemblyVersion(); }
        }

        public static string ProductInfo
        {
            get { return Assembly.GetEntryAssembly().AssemblyProduct(); }
        }

        /// <summary>
        ///   Записывает сообщение в журнал
        /// </summary>
        /// <param name = "logMessage"></param>
        public static void LogMessage(string logMessage)
        {
            Logger.Write(logMessage);
        }

        //private IApplicationExceptionHandler _exceptionHandler;

        /// <summary>
        ///   Метод обработки исключения в соответствие с установленной политикой
        /// </summary>
        /// <param name = "exception">Исключение</param>
        /// <returns>Истина, если исключение обработано</returns>
        public static bool HandleException(Exception exception)
        {
            return ExceptionManager.HandleException(exception, DEFAULT_POLICY);
        }

        protected override void OnStartup(StartupEventArgs e)
        {

            this.DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);

            SetupBinds();

            SetupExceptionDialog();

            // Установка провайдера параметров соединения
            InitQueryProvider();

            if (e.Args.Length > 0)
                ProceedArgs(e.Args);

            SetupLocalization();
            base.OnStartup(e);
        }

        private static void SetupExceptionDialog()
        {
            Logger.SetContextItem("Версия клиента", string.Format("{0} - {1}", AssemblyVersionInfo, FileVersionInfo));
            HandleExceptionDialog.LogFileName = "\\UD\\trace.log";
            HandleExceptionDialog.ContextFilePath = LinqLogWriter.Instance.FilePath;

            LogMessage("Создан файл отладочных данных контекста: " + HandleExceptionDialog.ContextFilePath);
        }

        private static void SetupBinds()
        {
            _kernel = new StandardKernel();
            _kernel.Bind<ICoreLogger>().To<DefaultLogger>();
        }

        private void SetupLocalization()
        {
            LocalizationManager.Manager = new DefaultTelerikLocalizationManager();
        }

        private void ProceedArgs(string[] args)
        {

            ProjectStartupInfo.FastLoad = args.Any(x => x.ToUpper() == "/FAST");
            ProjectStartupInfo.CreateNewContract = args.Any(x => x.ToUpper() == "/NEW");
            ProjectStartupInfo.UpdateStatistics = args.Any(x => x.ToUpper() == "/UPDATE-STATISTICS");


            if (args.Any(x => x.ToUpper().Contains("/C")))
            {
                var a = args.FirstOrDefault(x => x.ToUpper().Contains("/C"));
                if (a == null) return;
                var i = Array.IndexOf(args, a);
                if (args.Length < i) return;
                if (i < 0 || i >= args.Count()) return;
                ProjectStartupInfo.Contracts = args[i + 1];
            }
        }



        void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            MainWindowViewModel.Instance.With(x => x.ActiveWorkspace).Do(x => x.CollectDiagnosticsData(e.Exception));

            e.Handled = App.HandleException(e.Exception);

        }

        private void InitQueryProvider()
        {
            LogMessage("Начало: InitQueryProvider()");
#if !DEBUG
           // ContextFactoryService.Instance.QueryLoginProvider = new StubQueryLoginProvider("UD", "sys", "XE");
            MCDomain.DataAccess.ContextFactoryService.Instance.QueryLoginProvider = new Dialogs.ServerConnectionDialog();
#else
            //MCDomain.DataAccess.ContextFactoryService.Instance.QueryLoginProvider = new Dialogs.ServerConnectionDialog();
            ContextFactoryService.Instance.QueryLoginProvider = new StubQueryLoginProvider("UD", "sys", "XE");
#endif

            // Подписка на событие ошибки создания контекста. Стандартная реакция - завершить процесс.
            ContextFactoryService.Instance.CreateFailed += ContextCreateFailed;
            ContextFactoryService.Instance.Connected += new EventHandler(Instance_Connected);
            LogMessage("Конец: InitQueryProvider()");
        }

        private SplashScreen _splashScreen;

        void Instance_Connected(object sender, EventArgs e)
        {
            if (_splashScreen == null)
            {
                _splashScreen = new SplashScreen("Resources/Promgaz1.png");
                _splashScreen.Show(true);
            }
        }

        private void ContextCreateFailed(object sender, EventParameterArgs<Exception> e)
        {
            LogMessage("Провайдер подключения вернул ошибку " + e.Parameter.With(x=>x.Message));
            LogMessage("Завершение приложения с кодом 0xFA");
            Shutdown(0xFA);
        }


    }
}
